home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / Obrn-A_1.6_lib.lha / oberon-a / source3.lha / source / framework / Events.mod < prev    next >
Text File  |  1995-06-29  |  14KB  |  626 lines

  1. (*************************************************************************
  2.  
  3.      $RCSfile: Events.mod $
  4.   Description: Implements classes for managing events
  5.  
  6.    Created by: fjc (Frank Copeland)
  7.     $Revision: 1.15 $
  8.       $Author: fjc $
  9.         $Date: 1995/06/21 17:03:01 $
  10.  
  11.   Copyright © 1994-1995, Frank Copeland.
  12.   Improvements and corrections by Helmuth Ritzer.
  13.   This file is part of the Oberon-A Library.
  14.   See Oberon-A.doc for conditions of use and distribution.
  15.  
  16. *************************************************************************)
  17.  
  18. <*  STANDARD- *> (* Non-portable code is allowed *)
  19. <*$ NilChk- *>
  20.  
  21. (*
  22. ** NIL checking is assumed to be disabled, and procedures make explicit
  23. ** checks for NIL pointers using ASSERT().
  24. *)
  25.  
  26. MODULE Events;
  27.  
  28. IMPORT
  29.   SYS := SYSTEM, Kernel, e := Exec, es := ExecSupport, i := Intuition,
  30.   gt := GadTools;
  31.  
  32.  
  33. TYPE
  34.  
  35.   Signal *= POINTER TO SignalRec;
  36.   SignalRec *= RECORD
  37.     sigBit *: SHORTINT;
  38.   END; (* SignalRec *)
  39.  
  40.  
  41. CONST
  42.   Pass     *= 0;
  43.   Continue *= 1;
  44.   Stop     *= 2;
  45.   StopAll  *= 3;
  46.  
  47.   NoGC *= 0;       (* Turn off garbage collection *)
  48.  
  49. TYPE
  50.  
  51.   MessagePort *= POINTER TO MessagePortRec;
  52.   MessagePortRec *= RECORD (SignalRec)
  53.     port -: e.MsgPortPtr;
  54.   END; (* MessagePortRec *)
  55.  
  56.  
  57. TYPE
  58.  
  59.   IdcmpPort *= POINTER TO IdcmpPortRec;
  60.   IdcmpPortRec * = RECORD (MessagePortRec) END;
  61.  
  62.  
  63. TYPE
  64.  
  65.   GadToolsPort *= POINTER TO GadToolsPortRec;
  66.   GadToolsPortRec *= RECORD (IdcmpPortRec) END;
  67.  
  68.  
  69. CONST
  70.  
  71.   NumSignals = 32; (* The maximum number of signals for a Task. *)
  72.  
  73.  
  74. TYPE
  75.  
  76.   EventLoop *= POINTER TO EventLoopRec;
  77.   EventLoopRec *= RECORD
  78.     sigBits      : SET;
  79.     signal       : ARRAY NumSignals OF Signal;
  80.     collectFreq,
  81.     collectCount : INTEGER;
  82.   END; (* EventLoopRec *)
  83.  
  84. VAR
  85.  
  86.   loops : EventLoop;
  87.  
  88. (*-----------------------------------*)
  89. PROCEDURE (h : Signal) HandleSig * () : INTEGER;
  90.  
  91. BEGIN (* HandleSig *)
  92.   HALT (99);
  93.   RETURN StopAll
  94. END HandleSig;
  95.  
  96.  
  97. (*-----------------------------------*)
  98. PROCEDURE SimpleLoop * ( sig : Signal; collectFreq : INTEGER );
  99.  
  100.   VAR signalsReceived : SET; result, collectCount : INTEGER;
  101.  
  102. BEGIN (* SimpleLoop *)
  103.   ASSERT (sig # NIL, 97);
  104.   ASSERT (collectFreq >= NoGC, 97);
  105.   collectCount := collectFreq;
  106.   REPEAT
  107.     signalsReceived := e.Wait ({sig.sigBit});
  108.     result := sig.HandleSig ();
  109.     IF collectFreq # NoGC THEN
  110.       IF collectCount = 1 THEN
  111.         (* i.DisplayBeep (NIL); *)
  112.         Kernel.GC;
  113.         collectCount := collectFreq
  114.       ELSE
  115.         DEC (collectCount)
  116.       END
  117.     END
  118.   UNTIL (result > Continue);
  119. END SimpleLoop;
  120.  
  121.  
  122. (*-----------------------------------*)
  123. PROCEDURE (mp : MessagePort) HandleMsg * ( msg : e.MessagePtr ) : INTEGER;
  124.  
  125. BEGIN (* HandleMsg *)
  126.   HALT (99);
  127.   RETURN StopAll
  128. END HandleMsg;
  129.  
  130.  
  131. (*-----------------------------------*)
  132. PROCEDURE (mp : MessagePort) HandleSig * () : INTEGER;
  133.  
  134.   VAR result : INTEGER; msg : e.MessagePtr;
  135.  
  136. BEGIN (* HandleSig *)
  137.   result := Pass;
  138.   LOOP
  139.     msg := e.GetMsg (mp.port);
  140.     IF msg = NIL THEN EXIT END;
  141.     result := mp.HandleMsg (msg);
  142.     IF result = Pass THEN e.ReplyMsg (msg) END;
  143.     IF result > Continue THEN EXIT END
  144.   END;
  145.   RETURN result
  146. END HandleSig;
  147.  
  148.  
  149. (*-----------------------------------*)
  150. PROCEDURE (mp : MessagePort) FlushPort * ();
  151.  
  152.   VAR msg : e.MessagePtr;
  153.  
  154. BEGIN (* FlushPort *)
  155.   e.Forbid ();
  156.     LOOP
  157.       msg := e.GetMsg (mp.port);
  158.       IF msg = NIL THEN EXIT END;
  159.       e.ReplyMsg (msg)
  160.     END;
  161.   e.Permit ()
  162. END FlushPort;
  163.  
  164.  
  165. (*-----------------------------------*)
  166. PROCEDURE (mp : MessagePort) AttachPort* ( port : e.MsgPortPtr );
  167.  
  168. BEGIN (* AttachPort *)
  169.   ASSERT (port # NIL, 97);
  170.   mp.sigBit := port.sigBit;
  171.   mp.port := port;
  172. END AttachPort;
  173.  
  174.  
  175. (*-----------------------------------*)
  176. PROCEDURE (mp : MessagePort) DetachPort *;
  177.  
  178. BEGIN (* DetachPort *)
  179.   mp.FlushPort ();
  180.   mp.port := NIL;
  181.   mp.sigBit := -1;
  182. END DetachPort;
  183.  
  184.  
  185. (*-----------------------------------*)
  186. PROCEDURE (mp : MessagePort) MakePort *
  187.   ( name : ARRAY OF CHAR; priority : SHORTINT )
  188.   : BOOLEAN;
  189.  
  190.   VAR port : e.MsgPortPtr;
  191.  
  192. <*$CopyArrays-*>
  193. BEGIN (* MakePort *)
  194.   port := es.CreatePort (name, priority);
  195.   IF port # NIL THEN mp.AttachPort (port); RETURN TRUE
  196.   ELSE RETURN FALSE
  197.   END
  198. END MakePort;
  199.  
  200.  
  201. (*-----------------------------------*)
  202. PROCEDURE (mp : MessagePort) DeletePort *;
  203.  
  204. BEGIN (* DeletePort *)
  205.   e.Forbid ();
  206.     mp.FlushPort ();
  207.     es.DeletePort (mp.port);
  208.   e.Permit ();
  209.   mp.port := NIL;
  210.   mp.sigBit := -1
  211. END DeletePort;
  212.  
  213.  
  214. (*-----------------------------------*)
  215.  
  216. <*$ < ReturnChk- *>
  217.  
  218. PROCEDURE (ip : IdcmpPort) DefaultHandler *
  219.   ( msg : i.IntuiMessagePtr; flag : INTEGER )
  220.   : INTEGER;
  221.  
  222. BEGIN (* DefaultHandler *)
  223.   HALT (99);
  224.   RETURN Pass
  225. END DefaultHandler;
  226.  
  227. PROCEDURE (ip : IdcmpPort) HandleSizeVerify *
  228.   ( msg : i.IntuiMessagePtr )
  229.   : INTEGER;
  230.  
  231. BEGIN (* HandleSizeVerify *)
  232.   RETURN Pass
  233. END HandleSizeVerify;
  234.  
  235. PROCEDURE (ip : IdcmpPort) HandleNewSize *
  236.   ( msg : i.IntuiMessagePtr )
  237.   : INTEGER;
  238.  
  239. BEGIN (* HandleNewSize *)
  240.   RETURN Pass
  241. END HandleNewSize;
  242.  
  243. PROCEDURE (ip : IdcmpPort) HandleRefreshWindow *
  244.   ( msg : i.IntuiMessagePtr )
  245.   : INTEGER;
  246.  
  247. BEGIN (* HandleRefreshWindow *)
  248.   RETURN Pass
  249. END HandleRefreshWindow;
  250.  
  251. PROCEDURE (ip : IdcmpPort) HandleMouseButtons *
  252.   ( msg : i.IntuiMessagePtr )
  253.   : INTEGER;
  254.  
  255. BEGIN (* HandleMouseButtons *)
  256.   RETURN Pass
  257. END HandleMouseButtons;
  258.  
  259. PROCEDURE (ip : IdcmpPort) HandleMouseMove *
  260.   ( msg : i.IntuiMessagePtr )
  261.   : INTEGER;
  262.  
  263. BEGIN (* HandleMouseMove *)
  264.   RETURN Pass
  265. END HandleMouseMove;
  266.  
  267. PROCEDURE (ip : IdcmpPort) HandleGadgetDown *
  268.   ( msg : i.IntuiMessagePtr )
  269.   : INTEGER;
  270.  
  271. BEGIN (* HandleGadgetDown *)
  272.   RETURN Pass
  273. END HandleGadgetDown;
  274.  
  275. PROCEDURE (ip : IdcmpPort) HandleGadgetUp *
  276.   ( msg : i.IntuiMessagePtr )
  277.   : INTEGER;
  278.  
  279. BEGIN (* HandleGadgetUp *)
  280.   RETURN Pass
  281. END HandleGadgetUp;
  282.  
  283. PROCEDURE (ip : IdcmpPort) HandleReqSet *
  284.   ( msg : i.IntuiMessagePtr )
  285.   : INTEGER;
  286.  
  287. BEGIN (* HandleReqSet *)
  288.   RETURN Pass
  289. END HandleReqSet;
  290.  
  291. PROCEDURE (ip : IdcmpPort) HandleMenuPick *
  292.   ( msg : i.IntuiMessagePtr )
  293.   : INTEGER;
  294.  
  295. BEGIN (* HandleMenuPick *)
  296.   RETURN Pass
  297. END HandleMenuPick;
  298.  
  299. PROCEDURE (ip : IdcmpPort) HandleCloseWindow *
  300.   ( msg : i.IntuiMessagePtr )
  301.   : INTEGER;
  302.  
  303. BEGIN (* HandleCloseWindow *)
  304.   RETURN Pass
  305. END HandleCloseWindow;
  306.  
  307. PROCEDURE (ip : IdcmpPort) HandleRawKey *
  308.   ( msg : i.IntuiMessagePtr )
  309.   : INTEGER;
  310.  
  311. BEGIN (* HandleRawKey *)
  312.   RETURN Pass
  313. END HandleRawKey;
  314.  
  315. PROCEDURE (ip : IdcmpPort) HandleReqVerify *
  316.   ( msg : i.IntuiMessagePtr )
  317.   : INTEGER;
  318.  
  319. BEGIN (* HandleReqVerify *)
  320.   RETURN Pass
  321. END HandleReqVerify;
  322.  
  323. PROCEDURE (ip : IdcmpPort) HandleReqClear *
  324.   ( msg : i.IntuiMessagePtr )
  325.   : INTEGER;
  326.  
  327. BEGIN (* HandleReqClear *)
  328.   RETURN Pass
  329. END HandleReqClear;
  330.  
  331. PROCEDURE (ip : IdcmpPort) HandleMenuVerify *
  332.   ( msg : i.IntuiMessagePtr )
  333.   : INTEGER;
  334.  
  335. BEGIN (* HandleMenuVerify *)
  336.   RETURN Pass
  337. END HandleMenuVerify;
  338.  
  339. PROCEDURE (ip : IdcmpPort) HandleNewPrefs *
  340.   ( msg : i.IntuiMessagePtr )
  341.   : INTEGER;
  342.  
  343. BEGIN (* HandleNewPrefs *)
  344.   RETURN Pass
  345. END HandleNewPrefs;
  346.  
  347. PROCEDURE (ip : IdcmpPort) HandleDiskInserted *
  348.   ( msg : i.IntuiMessagePtr )
  349.   : INTEGER;
  350.  
  351. BEGIN (* HandleDiskInserted *)
  352.   RETURN Pass
  353. END HandleDiskInserted;
  354.  
  355. PROCEDURE (ip : IdcmpPort) HandleDiskRemoved *
  356.   ( msg : i.IntuiMessagePtr )
  357.   : INTEGER;
  358.  
  359. BEGIN (* HandleDiskRemoved *)
  360.   RETURN Pass
  361. END HandleDiskRemoved;
  362.  
  363. PROCEDURE (ip : IdcmpPort) HandleActiveWindow *
  364.   ( msg : i.IntuiMessagePtr )
  365.   : INTEGER;
  366.  
  367. BEGIN (* HandleActiveWindow *)
  368.   RETURN Pass
  369. END HandleActiveWindow;
  370.  
  371. PROCEDURE (ip : IdcmpPort) HandleInactiveWindow *
  372.   ( msg : i.IntuiMessagePtr )
  373.   : INTEGER;
  374.  
  375. BEGIN (* HandleInactiveWindow *)
  376.   RETURN Pass
  377. END HandleInactiveWindow;
  378.  
  379. PROCEDURE (ip : IdcmpPort) HandleDeltaMove *
  380.   ( msg : i.IntuiMessagePtr )
  381.   : INTEGER;
  382.  
  383. BEGIN (* HandleDeltaMove *)
  384.   RETURN Pass
  385. END HandleDeltaMove;
  386.  
  387. PROCEDURE (ip : IdcmpPort) HandleVanillaKey *
  388.   ( msg : i.IntuiMessagePtr )
  389.   : INTEGER;
  390.  
  391. BEGIN (* HandleVanillaKey *)
  392.   RETURN Pass
  393. END HandleVanillaKey;
  394.  
  395. PROCEDURE (ip : IdcmpPort) HandleIntuiTicks *
  396.   ( msg : i.IntuiMessagePtr )
  397.   : INTEGER;
  398.  
  399. BEGIN (* HandleIntuiTicks *)
  400.   RETURN Pass
  401. END HandleIntuiTicks;
  402.  
  403. PROCEDURE (ip : IdcmpPort) HandleIdcmpUpdate *
  404.   ( msg : i.IntuiMessagePtr )
  405.   : INTEGER;
  406.  
  407. BEGIN (* HandleIdcmpUpdate *)
  408.   RETURN Pass
  409. END HandleIdcmpUpdate;
  410.  
  411. PROCEDURE (ip : IdcmpPort) HandleMenuHelp *
  412.   ( msg : i.IntuiMessagePtr )
  413.   : INTEGER;
  414.  
  415. BEGIN (* HandleMenuHelp *)
  416.   RETURN Pass
  417. END HandleMenuHelp;
  418.  
  419. PROCEDURE (ip : IdcmpPort) HandleChangeWindow *
  420.   ( msg : i.IntuiMessagePtr )
  421.   : INTEGER;
  422.  
  423. BEGIN (* HandleChangeWindow *)
  424.   RETURN Pass
  425. END HandleChangeWindow;
  426.  
  427. PROCEDURE (ip : IdcmpPort) HandleGadgetHelp *
  428.   ( msg : i.IntuiMessagePtr )
  429.   : INTEGER;
  430.  
  431. BEGIN (* HandleGadgetHelp *)
  432.   RETURN Pass
  433. END HandleGadgetHelp;
  434.  
  435. <*$ > *>
  436.  
  437.  
  438. (*-----------------------------------*)
  439. PROCEDURE (ip : IdcmpPort) HandleMsg* ( msg : e.MessagePtr ) : INTEGER;
  440.  
  441.   VAR
  442.     intuiMessage : i.IntuiMessagePtr;
  443.     class : SET; flag, result : INTEGER;
  444.  
  445. BEGIN (* HandleMsg *)
  446.   intuiMessage := SYS.VAL (i.IntuiMessagePtr, msg);
  447.   class := intuiMessage.class;
  448.   flag := 0; WHILE (flag < 32) & ~(flag IN class) DO INC (flag) END;
  449.   CASE flag OF
  450.     i.sizeVerify     : result := ip.HandleSizeVerify (intuiMessage) |
  451.     i.newSize        : result := ip.HandleNewSize (intuiMessage) |
  452.     i.refreshWindow  : result := ip.HandleRefreshWindow (intuiMessage) |
  453.     i.mouseButtons   : result := ip.HandleMouseButtons (intuiMessage) |
  454.     i.mouseMove      : result := ip.HandleMouseMove (intuiMessage) |
  455.     i.gadgetDown     : result := ip.HandleGadgetDown (intuiMessage) |
  456.     i.gadgetUp       : result := ip.HandleGadgetUp (intuiMessage) |
  457.     i.reqSet         : result := ip.HandleReqSet (intuiMessage) |
  458.     i.menuPick       : result := ip.HandleMenuPick (intuiMessage) |
  459.     i.closeWindow    : result := ip.HandleCloseWindow (intuiMessage) |
  460.     i.rawKey         : result := ip.HandleRawKey (intuiMessage) |
  461.     i.reqVerify      : result := ip.HandleReqVerify (intuiMessage) |
  462.     i.reqClear       : result := ip.HandleReqClear (intuiMessage) |
  463.     i.menuVerify     : result := ip.HandleMenuVerify (intuiMessage) |
  464.     i.newPrefs       : result := ip.HandleNewPrefs (intuiMessage) |
  465.     i.diskInserted   : result := ip.HandleDiskInserted (intuiMessage) |
  466.     i.diskRemoved    : result := ip.HandleDiskRemoved (intuiMessage) |
  467.     i.activeWindow   : result := ip.HandleActiveWindow (intuiMessage) |
  468.     i.inactiveWindow : result := ip.HandleInactiveWindow (intuiMessage) |
  469.     i.deltaMove      : result := ip.HandleDeltaMove (intuiMessage) |
  470.     i.vanillaKey     : result := ip.HandleVanillaKey (intuiMessage) |
  471.     i.intuiTicks     : result := ip.HandleIntuiTicks (intuiMessage) |
  472.     i.idcmpUpdate    : result := ip.HandleIdcmpUpdate (intuiMessage) |
  473.     i.menuHelp       : result := ip.HandleMenuHelp (intuiMessage) |
  474.     i.changeWindow   : result := ip.HandleChangeWindow (intuiMessage) |
  475.     i.gadgetHelp     : result := ip.HandleGadgetHelp (intuiMessage) |
  476.   ELSE result := ip.DefaultHandler (intuiMessage, flag)
  477.   END;
  478.   RETURN result
  479. END HandleMsg;
  480.  
  481.  
  482. (*-----------------------------------*)
  483. PROCEDURE (ip : IdcmpPort) SetupWindow* (window : i.WindowPtr);
  484.  
  485. BEGIN (* SetupWindow *)
  486. END SetupWindow;
  487.  
  488.  
  489. (*-----------------------------------*)
  490. PROCEDURE (ip : IdcmpPort) CleanupWindow* (window : i.WindowPtr);
  491.  
  492. BEGIN (* CleanupWindow *)
  493. END CleanupWindow;
  494.  
  495.  
  496. (*-----------------------------------*)
  497. PROCEDURE (gtp : GadToolsPort) HandleSig * () : INTEGER;
  498.  
  499.   VAR result : INTEGER; msg : i.IntuiMessagePtr;
  500.  
  501. BEGIN (* HandleSig *)
  502.   result := Pass;
  503.   ASSERT (gtp.port # NIL, 97);
  504.   LOOP
  505.     msg := gt.GetIMsg (gtp.port);
  506.     IF msg = NIL THEN EXIT END;
  507.     result := gtp.HandleMsg (SYS.VAL (e.MessagePtr, msg));
  508.     IF result = Pass THEN gt.ReplyIMsg (msg) END;
  509.     IF result > Continue THEN EXIT END
  510.   END;
  511.   RETURN result
  512. END HandleSig;
  513.  
  514.  
  515. (*-----------------------------------*)
  516. PROCEDURE (gtp : GadToolsPort) FlushPort * ();
  517.  
  518.   VAR msg : i.IntuiMessagePtr;
  519.  
  520. BEGIN (* FlushPort *)
  521.   ASSERT (gtp.port # NIL, 97);
  522.   e.Forbid ();
  523.     LOOP
  524.       msg := gt.GetIMsg (gtp.port);
  525.       IF msg = NIL THEN EXIT END;
  526.       gt.ReplyIMsg (msg)
  527.     END;
  528.   e.Permit ()
  529. END FlushPort;
  530.  
  531.  
  532. (*-----------------------------------*)
  533. PROCEDURE InitEventLoop* ( el : EventLoop );
  534.  
  535.   VAR index : INTEGER;
  536.  
  537. BEGIN (* InitEventLoop *)
  538.   ASSERT (el # NIL, 97);
  539.   el.sigBits := {};
  540.   FOR index := 0 TO NumSignals - 1 DO
  541.     el.signal [index] := NIL
  542.   END;
  543.   el.collectFreq := NoGC;
  544. END InitEventLoop;
  545.  
  546.  
  547. (*-----------------------------------*)
  548. PROCEDURE (el: EventLoop) AddSignal* ( signal : Signal ) : Signal;
  549.  
  550.   VAR sigBit : SHORTINT; oldSignal : Signal;
  551.  
  552. BEGIN (* AddSignal *)
  553.   ASSERT (el # NIL, 97);
  554.   ASSERT (signal # NIL, 97);
  555.   sigBit := signal.sigBit;
  556.   oldSignal := el.signal [sigBit];
  557.   INCL (el.sigBits, sigBit);
  558.   el.signal [sigBit] := signal;
  559.   RETURN oldSignal
  560. END AddSignal;
  561.  
  562.  
  563. (*-----------------------------------*)
  564. PROCEDURE (el: EventLoop) RemoveSignal* ( signal : Signal );
  565.  
  566.   VAR sigBit : SHORTINT;
  567.  
  568. BEGIN (* RemoveSignal *)
  569.   ASSERT (el # NIL, 97);
  570.   ASSERT (signal # NIL, 97);
  571.   sigBit := signal.sigBit;
  572.   IF el.signal [sigBit] = signal THEN
  573.     el.signal [sigBit] := NIL;
  574.     EXCL (el.sigBits, sigBit);
  575.   END
  576. END RemoveSignal;
  577.  
  578.  
  579. (*-----------------------------------*)
  580. PROCEDURE (el: EventLoop) Collect* ( collectFreq : INTEGER );
  581.  
  582. BEGIN (* Collect *)
  583.   ASSERT (collectFreq >= NoGC, 97);
  584.   el.collectFreq := collectFreq;
  585.   el.collectCount := collectFreq;
  586. END Collect;
  587.  
  588.  
  589. (*-----------------------------------*)
  590. PROCEDURE (el : EventLoop) Do*;
  591.  
  592.   VAR
  593.     signalsReceived : SET; sigBit : SHORTINT; result : INTEGER;
  594.     signal : Signal;
  595.  
  596. BEGIN (* Loop *)
  597.   ASSERT (el # NIL, 97);
  598.   WHILE el.sigBits # {} DO
  599.     signalsReceived := e.Wait (el.sigBits);
  600.     FOR sigBit := 0 TO NumSignals - 1 DO
  601.       IF sigBit IN signalsReceived THEN
  602.         signal := el.signal [sigBit];
  603.         ASSERT (signal # NIL, 97);
  604.         result := signal.HandleSig ();
  605.         IF result = Stop THEN
  606.           el.signal [sigBit] := NIL;
  607.           EXCL (el.sigBits, sigBit)
  608.         ELSIF result = StopAll THEN
  609.           el.sigBits := {}
  610.         END
  611.       END
  612.     END;
  613.     IF el.collectFreq # NoGC THEN
  614.       IF el.collectCount = 1 THEN
  615.         (* i.DisplayBeep (NIL); *)
  616.         Kernel.GC;
  617.         el.collectCount := el.collectFreq
  618.       ELSE
  619.         DEC (el.collectCount)
  620.       END
  621.     END;
  622.   END
  623. END Do;
  624.  
  625. END Events.
  626.